package tss.clientGui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.metal.MetalLookAndFeel;

import tss.common.ExtensionStates;
import tss.common.LineStates;

public class ClientUI {

	private final int PHONE_ONHOOK = 0;
	private final int PHONE_RINGING = 1;
	private final int PHONE_OFFHOOK = 2;
	
	private ClientProcessor service;
	
	// message Window
	private JFrame messageWindow;
	private JTextArea messageTextArea;
	
	
	//inputs from connection
	private JTextField hostTextField;
	private JTextField portTextField;
	private JButton connectButton;
	
	//inputs from phone
	private JFrame mainWindow;
	private JButton[] phoneButtons;
	private BufferedImage[] phoneImageBuffer;
	private JLabel[] phoneImages;
	private JPanel[] phonePanels;
	
	// unhook panel
	private JButton phoneActionButton;

	public ClientUI(ClientProcessor service) {
		this.service = service;
		
		try {
			UIManager.setLookAndFeel(new MetalLookAndFeel());
		} catch (UnsupportedLookAndFeelException e) { }
		
		createMainWindow();
		createMessageWindow();
		
		attachEventListeners();
		
		showMessageWindow();
		showMainWindow();
	}
	
	private void attachEventListeners() {
		// Window Closing
		WindowAdapter windowAdapter = 
		new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				service.onWindowClosing();
			}
		};
		
		mainWindow.addWindowListener(windowAdapter);
		messageWindow.addWindowListener(windowAdapter);
		
		// Connect Button
		connectButton.addActionListener(
			new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					int port = 0;
					try {
						port = Integer.parseInt(portTextField.getText());
					} catch (NumberFormatException ex) { }
 					if (service.onConnectClick(hostTextField.getText(), port))
						connectButton.setEnabled(false);
				}
			}
		);
		
		for(int i = 0; i < 16; i++) {
			final int j = i;
			phoneButtons[i].addActionListener(
				new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						service.onPhoneExtensionClick(j);
					}
				}
			);
		}
		
		phoneActionButton.addActionListener(
			new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					service.onPhoneActionClick();
				}
 			}
		);
	}
	
	public void setActionState(boolean enabled, String text) {
		phoneActionButton.setEnabled(enabled);
		phoneActionButton.setText(text);
	}
	
	public void writeMessage(String message) {
		messageTextArea.append(message + "\n");
		messageWindow.repaint();
	}
	
	public void setCurrentPhone(int extension) {
		extension--; 
		phonePanels[extension].setBackground(Color.BLUE);
	}
	
	public void setPhoneLineState(int extension, LineStates state) {
		extension--;
		if (extension < 16 && extension > -1) {
			JButton phoneButton = phoneButtons[extension];
			JLabel phoneImage = phoneImages[extension];
			switch(state) {
				case Busy:
					phoneButton.setBackground(Color.GRAY);
					phoneImage.setIcon(new ImageIcon(phoneImageBuffer[PHONE_ONHOOK]));
					break;
				case Connecting:
					phoneButton.setBackground(Color.WHITE);
					phoneImage.setIcon(new ImageIcon(phoneImageBuffer[PHONE_ONHOOK]));
					break;
				case Dialing:
					phoneButton.setBackground(Color.YELLOW);
					phoneImage.setIcon(new ImageIcon(phoneImageBuffer[PHONE_OFFHOOK]));
					break;
				case Ringing:
					phoneButton.setBackground(Color.YELLOW);
					phoneImage.setIcon(new ImageIcon(phoneImageBuffer[PHONE_RINGING]));
					break;
				case Talking:
					phoneButton.setBackground(Color.ORANGE);
					phoneImage.setIcon(new ImageIcon(phoneImageBuffer[PHONE_OFFHOOK]));
					break;
				case Terminating:
					phoneButton.setBackground(Color.PINK);
					phoneImage.setIcon(new ImageIcon(phoneImageBuffer[PHONE_ONHOOK]));
					break;
				case Open:
					phoneButton.setBackground(Color.GREEN);
					phoneImage.setIcon(new ImageIcon(phoneImageBuffer[PHONE_ONHOOK]));
					break;
				case Error:
				default:
					phoneButton.setBackground(Color.BLACK);
					phoneImage.setIcon(new ImageIcon(phoneImageBuffer[PHONE_ONHOOK]));
					break;
			}
		}
	}
	
	public void setPhoneState(int extension, ExtensionStates state) {
		extension--;
		if (extension < 16 && extension > -1) {
			JButton phoneButton = phoneButtons[extension];
			JLabel phoneImage = phoneImages[extension];
			
			switch(state) {
				case Available:
					phoneButton.setBackground(Color.GREEN);
					phoneImage.setIcon(new ImageIcon(phoneImageBuffer[PHONE_ONHOOK]));
					break;
				case Busy:
					phoneButton.setBackground(Color.YELLOW);
					phoneImage.setIcon(new ImageIcon(phoneImageBuffer[PHONE_OFFHOOK]));					
					break;
				case Unavailable:
				default:
					phoneButton.setBackground(Color.RED);
					phoneImage.setIcon(new ImageIcon(phoneImageBuffer[PHONE_ONHOOK]));		
			}
		}
	}

	private void showMessageWindow() {
		messageWindow.pack();
		messageWindow.setVisible(true);
	}
	
	private void createMessageWindow() {
		messageWindow = new JFrame();
		messageWindow.setPreferredSize(new Dimension(450, 115));
		messageWindow.setTitle("Telephone Client Messages");
		messageWindow.setBounds(450, 0, 300, 75);
		messageWindow.setResizable(true);
		
		messageTextArea = new JTextArea();
		messageTextArea.setBackground(Color.BLACK);
		messageTextArea.setForeground(Color.GREEN);
		
		JScrollPane messageScroll = new JScrollPane(messageTextArea);
		JPanel messagePanel = new JPanel(new BorderLayout());
		messagePanel.add(messageScroll);	
		
		messageWindow.add(messagePanel);
	}
	
	private void showMainWindow() {
		messageWindow.pack();
		messageWindow.setVisible(true);
	}
	
	private void createMainWindow() {
		//initializing the frame
		mainWindow = new JFrame();
		mainWindow.setPreferredSize(new Dimension(450,700));
		mainWindow.setResizable(false);
		mainWindow.setTitle("Telephone Client");
		mainWindow.setLayout(new FlowLayout());
					
		//add connection panel to frame
		mainWindow.add(createConnectionPanel());
		mainWindow.add(createPhonePanel());
		mainWindow.add(createActionPanel());
		mainWindow.add(createLogoPanel());
		
		mainWindow.pack();
		mainWindow.setVisible(true);
	}
	
	private JPanel createLogoPanel(){
		JPanel logoPanel = new JPanel(new FlowLayout());
		BufferedImage[] logoPic = new BufferedImage[2];
		
		try{
			logoPic[0] = ImageIO.read(new File("src//tss//resources//engg.jpg"));
			logoPic[1] = ImageIO.read(new File("src//tss//resources//UofC.gif"));
		}
		catch(Exception e){
			e.getStackTrace();
		}
		
		logoPanel.add(new JLabel(new ImageIcon(logoPic[0])));
		logoPanel.add(new JLabel(new ImageIcon(logoPic[1])));
		
		return logoPanel;
	}
	
	private JPanel createActionPanel() {
		//add a panel with disconnect
		JPanel actionPanel = new JPanel();
		actionPanel.setPreferredSize(new Dimension(430,35));
		phoneActionButton = new JButton("No Action");
		phoneActionButton.setEnabled(false);
		
		actionPanel.add(phoneActionButton);
		
		return actionPanel;
	}
	
	
	private JPanel createPhonePanel(){
		//adding the buttons for the phone and there graphics next
		JPanel phonePanel = new JPanel(new GridLayout(4,4));
		
		// Create Buttons
		phoneButtons = new JButton[16];
		for(int i = 0; i < 16; i++){
			phoneButtons[i] = new JButton(String.valueOf(i + 1));
			phoneButtons[i].setPreferredSize(new Dimension(100,25));
			phoneButtons[i].setBackground(Color.RED);
			phoneButtons[i].setOpaque(true);
		}
		
		// Load Image Buffer
		phoneImageBuffer = new BufferedImage[3];
		
		try {
			phoneImageBuffer[0] = ImageIO.read(new File("src//tss//resources//phone1.jpg"));
			phoneImageBuffer[1] = ImageIO.read(new File("src//tss//resources//phone2.jpg"));
			phoneImageBuffer[2] = ImageIO.read(new File("src//tss//resources//phone3.jpg"));
		} catch(Exception e) {
			e.getStackTrace();
		}
		
		// Create Phone Images
		phoneImages = new JLabel[16];
		for(int i = 0; i<16; i++){
			phoneImages[i] = new JLabel(new ImageIcon(phoneImageBuffer[0]));
			phoneImages[i].setPreferredSize(new Dimension(80, 60));
		}
				
		// Create Phone Panels
		phonePanels = new JPanel[16];
		for (int i = 0; i < 16; i++) {
			phonePanels[i] = new JPanel(new FlowLayout());
			phonePanels[i].setPreferredSize(new Dimension(100,100));
			phonePanels[i].add(phoneImages[i]);
			phonePanels[i].add(phoneButtons[i]);
			phonePanel.add(phonePanels[i]);
		}
			
		return phonePanel;
		
	}
	
	private JPanel createConnectionPanel(){
		JPanel connectionPanel = new JPanel(new GridLayout(1,3));
		connectionPanel.setPreferredSize(new Dimension(400,50));
		
		JPanel hostPanel = new JPanel(new FlowLayout());
		
		JLabel hostLabel = new JLabel("Host");
		hostLabel.setPreferredSize(new Dimension(130, 15));
		hostPanel.add(hostLabel);
		
		hostTextField = new JTextField();
		hostTextField.setPreferredSize(new Dimension(130, 25));
		hostPanel.add(hostTextField);
		
		connectionPanel.add(hostPanel);
		
		JPanel portPanel = new JPanel(new FlowLayout());
		
		JLabel portLabel = new JLabel("Port");
		portLabel.setPreferredSize(new Dimension(130, 15));
		portPanel.add(portLabel);
		
		portTextField = new JTextField();
		portTextField.setPreferredSize(new Dimension(130, 25));
		portPanel.add(portTextField);
		
		connectionPanel.add(portPanel);
		
		JPanel connectPanel = new JPanel(new FlowLayout());
		JLabel connectLabel = new JLabel("");
		connectLabel.setPreferredSize(new Dimension(130, 15));
		connectPanel.add(connectLabel);
			
		connectButton = new JButton("CONNECT");
		connectButton.setPreferredSize(new Dimension(130,25));
		connectPanel.add(connectButton);
		
		connectionPanel.add(connectPanel);

		return connectionPanel;
	}	
}
